package com.lifep.collect.platform.web;

import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.lifep.collect.platform.collect.Collector;
import com.lifep.collect.platform.collect.Task;
import com.lifep.collect.platform.module.classloader.ModuleClassLoader;
import com.lifep.collect.platform.module.DmcDynamicModule;
import com.lifep.collect.platform.module.DmcModule;
import com.lifep.collect.platform.module.ModuleAnnotationApplicationContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.io.File;
import java.net.URL;
import java.util.Collections;

/**
 * @author: zw
 * @create: 2024-09-28 22:32
 * @description:
 **/
@RestController
@Slf4j
public class ModuleTestController {

    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void loadModule() throws Exception {
        // 模拟加载jar包
        String filePath = "/Users/lifep/IdeaProjects/wuhuichen/collect/collect-sub-module/target/collect-sub-module-0.0.1-SNAPSHOT-demo-assembly.jar";
        File file = new File(filePath);
        URL url = file.toURI().toURL();

        // 加载模块spring上下文
        AnnotationConfigApplicationContext moduleApplicationContext = loadModuleApplication(url);
        // 创建采集子模块
        DmcModule dynamicModule = new DmcDynamicModule("DEMO_INFO", moduleApplicationContext);

        // 模拟创建一个采集任务
        Task task = new Task(){
            @Override
            public String getName() {
                return "testName";
            }

            @Override
            public Integer getExecutionCount() {
                return 1;
            }
        };

        // 获取模块的采集器
        Collector collector = dynamicModule.getCollector("DEMO_INFO");

        // dmc平台的classloader。
        ClassLoader dmcClassLoader = Thread.currentThread().getContextClassLoader();
        try {
            // 模块内部classloader
            ClassLoader moduleClassLoader = collector.getClass().getClassLoader();
            // 切换classloader
            Thread.currentThread().setContextClassLoader(moduleClassLoader);
            // 执行采集模块的流程
            collector.collect(task);
        } catch (Throwable e) {
            log.error("执行采集失败", e);
        } finally {
            // 切换回classloader
            Thread.currentThread().setContextClassLoader(dmcClassLoader);
        }
    }

    private AnnotationConfigApplicationContext loadModuleApplication(URL url) {
        ClassLoader currentClassloader = Thread.currentThread().getContextClassLoader();
        ClassLoader moduleClassloader = new ModuleClassLoader(Collections.singletonList(url), applicationContext.getClassLoader(),
                Lists.newArrayList());

        try {
            Thread.currentThread().setContextClassLoader(moduleClassloader);
            // 扫描子模块相关包。
            ModuleAnnotationApplicationContext moduleAnnotationApplicationContext = new ModuleAnnotationApplicationContext("com.lifep.collect.module");
            // 设置父上下文为平台上下文
            moduleAnnotationApplicationContext.setParent(applicationContext);
            moduleAnnotationApplicationContext.setClassLoader(moduleClassloader);
            // 外部手动刷新
            moduleAnnotationApplicationContext.refresh();
            return moduleAnnotationApplicationContext;
        } catch (Throwable e) {
            CachedIntrospectionResults.clearClassLoader(moduleClassloader);
            log.error("执行loadModuleApplication失败 ", e);
            throw Throwables.propagate(e);
        } finally {
            Thread.currentThread().setContextClassLoader(currentClassloader);
        }
    }
}
